package com.segersten.kalaha

import java.util.logging.Logger;
import com.segersten.kalaha.domain.Event;
import com.segersten.kalaha.domain.EventType;

class TimeOutController {

	private static Logger LOG = Logger.getLogger(getClass().getCanonicalName());
	def kalahasettings

	def index = { render(text:"Welcome to the TimeOutController")}

	def cleanupGames = {
		//remove games that hasn't been played for 1 minute
		def inGameTickets = SessionTicket.findAll("select from SessionTicket as s where s.sessionId <> null")
		Date roundTimeOut = new Date(new Date().getTime()-Integer.parseInt(kalahasettings.roundDuration)*1000-5000) // + 5 seconds extra
		BoardSessionCache bsc = new BoardSessionCache()
		int count = 0
		inGameTickets.each { ticket ->
			BoardSession bs = bsc.get(ticket.sessionId)
			if (bs==null) {
				LOG.info("Removed old ticket ${ticket.sessionId}")
				ticket.delete()
			} else if (bs.lastUpdated.before(roundTimeOut)) {
				// Time out and remove
				LOG.info("${bs.sessionId} timed out");
				if (bs.nextActor==Actor.NONE) {
					LOG.error("Failed to time out game ${bs.sessionId}");
				} else {
					LOG.info("Stop game ${bs.sessionId}");
					// Stop game, but keep it online
					def eventType
					if (bs.nextActor == Actor.PLAYER_1) {
						eventType = EventType.PLAYER_1_TIMEOUT
					} else if (bs.nextActor == Actor.PLAYER_2) {
						eventType = EventType.PLAYER_2_TIMEOUT
					} else {
						throw new IllegalStateException("Unexpected actor " + bs.nextActor);
					}
					bs.addEvent(eventType, params.arg)
					count++
				}
			}
		}
		if (count>0) { LOG.info("Timed out ${count} games") }

		response.status = 200
		render(text:"OK")
	}

	def cleanupTickets = {
		//remove ticket that is not owned by a bot and hasn't been updated for 1 minute
		Date threeMinutesAgo = new Date(new Date().getTime()-60*1000)
		def waitingTickets = SessionTicket.findAll("select from SessionTicket as s where s.sessionId = null and s.lastUpdated < :p1 and s.ownerIsBot = false", [p1:threeMinutesAgo])
		waitingTickets.each { ticket ->
			LOG.info("Remove ticket owned by ${ticket.ownerId}")
			CanceledSessionTicket canceledTicket = new CanceledSessionTicket(ticketId:ticket.ticketId,
			ownerId:ticket.ownerId,created:new Date(),
			reason:CanceledSessionTicket.REASON_TIMED_OUT)
			canceledTicket.save()
			ticket.delete()
		}
		if (waitingTickets.size()>0) { LOG.info("Removed ${waitingTickets.size()} tickets") }

		response.status = 200
		render(text:"OK")
	}
}
